// #include <iostream>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/wait.h>
// #include <cstdio>
// #include <cstring>

// // 子进程写入管道的函数
// void ChildWrite(int wfd)
// {
//     char buffer[1024];
//     int cnt = 0;
//     while (true)
//     {                                                                                    // 子进程无限循环，持续向管道写入数据
//         snprintf(buffer, sizeof(buffer), "I am child,pid: %d ,cnt:%d", getpid(), cnt++); // 构造要写入的信息，包含子进程ID和计数
//         write(wfd, buffer, strlen(buffer));                                              // 向管道的写端写入数据
//         printf("child: %d\n", cnt);
//         close(wfd); // 关闭写端
//         sleep(2);
//         break;
//         // sleep(1);                                                                        // 暂停1秒
//     }
// }

// // 父进程从管道读取的函数
// void FatherRead(int rfd)
// {
//     char buffer[1024];
//     while (true)
//     {                                                      // 父进程无限循环，持续从管道读取数据
//         buffer[0] = 0;                                     // 初始化缓冲区
//         ssize_t n = read(rfd, buffer, sizeof(buffer) - 1); // 从管道的读端读取数据
//         if (n > 0)
//         {                                                      // 如果读取到数据
//             buffer[n] = '\0';                                  // 确保字符串以空字符结尾
//             std::cout << "child say: " << buffer << std::endl; // 输出读取到的信息
//             // sleep(2);
//         }
//         else
//         {
//             sleep(2);
//             std::cout << "n: " << n << std::endl;
//             std::cout << "子进程退出，我也退出";
//             break;
//         }
//     }
// }

// int main()
// {
//     // 1. 创建管道
//     int fds[2] = {0}; // fds[0]：管道的读端，fds[1]：管道的写端
//     int n = pipe(fds);
//     if (n < 0)
//     { // 如果创建管道失败
//         std::cerr << "pipe error" << std::endl;
//         return 1;
//     }
//     std::cout << "fds[0]:" << fds[0] << std::endl; // 输出读端文件描述符
//     std::cout << "fds[1]:" << fds[1] << std::endl; // 输出写端文件描述符

//     // 2. 创建子进程
//     pid_t id = fork();
//     if (id == 0)
//     { // 子进程
//         // 3. 关闭子进程不需要的读端
//         close(fds[0]);
//         ChildWrite(fds[1]); // 调用子进程写入函数
//         close(fds[1]);      // 关闭写端
//         exit(0);            // 子进程结束
//     }
//     else
//     { // 父进程
//         // 3. 关闭父进程不需要的写端
//         close(fds[1]);
//         FatherRead(fds[0]);      // 调用父进程读取函数
//         waitpid(id, nullptr, 0); // 父进程等待子进程结束
//         close(fds[0]);           // 关闭读端
//     }
//     return 0;
// }

// #include <iostream>
// #include <unistd.h>
// #include <cstring>

// int main()
// {
//     int fds[2];
//     pipe(fds);

//     // 写入数据
//     const char *msg1 = "Hello";
//     const char *msg2 = "World";
//     write(fds[1], msg1, strlen(msg1)); // 写入 "Hello"
//     write(fds[1], msg2, strlen(msg2)); // 写入 "World"
//     close(fds[1]);                     // 关闭写端

//     // 读取数据
//     char buffer[1024];
//     ssize_t n = read(fds[0], buffer, sizeof(buffer) - 1);
//     if (n > 0)
//     {
//         buffer[n] = '\0';
//         std::cout << "Read: " << buffer << std::endl;
//     }
//     close(fds[0]);

//     return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <sys/wait.h>

// int main()
// {
//     int fd[2];
//     pipe(fd);
//     pid_t pid = fork();

//     if (pid == 0)
//     {                 // 子进程（写端）
//         close(fd[0]); // 关闭读端
//         sleep(2);     // 模拟延迟写入
//         write(fd[1], "Hello", 6);
//         close(fd[1]);
//     }
//     else
//     {                 // 父进程（读端）
//         close(fd[1]); // 关闭写端
//         char buf[6];
//         printf("Reading... (will block until data arrives)\n");
//         read(fd[0], buf, 6); // 阻塞直到数据到达
//         printf("Read: %s\n", buf);
//         close(fd[0]);
//         wait(NULL);
//     }
//     return 0;
// }

// 2. 读端不读，写端被挂起直到管道有空间
// #include <stdio.h>
// #include <unistd.h>
// #include <string.h>
// #include <sys/wait.h>

// int main()
// {
//     int fd[2];
//     pipe(fd);
//     pid_t pid = fork();

//     if (pid == 0)
//     {                 // 子进程（读端）
//         close(fd[1]); // 关闭写端
//         sleep(10);    // 模拟长时间不读取
//         char buf[1024];
//         read(fd[0], buf, 1024); // 延迟读取
//         printf("Child finally read data\n");
//         close(fd[0]);
//     }
//     else
//     {                 // 父进程（写端）
//         close(fd[0]); // 关闭读端
//         const char *data = "Filling the pipe...";
//         int total = 0;
//         while (1)
//         { // 持续写入直到管道满
//             // sleep(1);
//             int bytes = write(fd[1], data, strlen(data) + 1);
//             if (bytes == -1)
//             {
//                 perror("write failed (pipe full)"); // 实际不会触发，会阻塞
//                 break;
//             }
//             total += bytes;
//             printf("Total written: %d bytes\n", total);
//         }
//         close(fd[1]);
//         wait(NULL);
//     }
//     return 0;
// }

// // 3. 写端关闭，读端正常读取
// #include <stdio.h>
// #include <unistd.h>
// #include <sys/wait.h>

// int main()
// {
//     int fd[2];
//     pipe(fd);
//     pid_t pid = fork();

//     if (pid == 0)
//     {                 // 子进程（读端）
//         close(fd[1]); // 关闭写端
//         char buf[12];
//         read(fd[0], buf, 12); // 读取数据
//         printf("Read: %s\n", buf);
//         printf("Trying to read again...\n");
//         ssize_t ret = read(fd[0], buf, 12); // 返回0（EOF）
//         printf("read returned %zd (EOF), exiting\n", ret);
//         close(fd[0]);
//     }
//     else
//     {                 // 父进程（写端）
//         close(fd[0]); // 关闭读端
//         write(fd[1], "Hello World", 12);
//         close(fd[1]); // 关闭写端，发送EOF
//         wait(NULL);
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <sys/wait.h>

// int main()
// {
//     int fd[2];
//     pipe(fd);
//     pid_t pid = fork();

//     if (pid == 0)
//     {                 // 子进程（写端）
//         close(fd[0]); // 关闭读端
//         sleep(1);     // 确保父进程关闭了读端
//         printf("Writing to pipe...\n");
//         if (write(fd[1], "Hello", 6) == -1)
//         {
//             perror("write failed"); // 会触发
//         }
//         close(fd[1]);
//     }
//     else
//     {                 // 父进程（读端）
//         close(fd[0]); // 关闭读端（关键操作）
//         close(fd[1]); // 父进程不操作写端
//         int status;
//         wait(&status);
//         if (WIFSIGNALED(status))
//         {
//             printf("Child killed by signal %d (SIGPIPE)\n", WTERMSIG(status));
//         }
//     }
//     return 0;
// }

// 测试管道大小

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>

int main()
{
    int fd[2];
    pipe(fd); // 创建管道

    // 设置写端为非阻塞模式
    fcntl(fd[1], F_SETFL, O_NONBLOCK);

    pid_t pid = fork();
    if (pid == 0)
    {                 // 子进程（写入端）
        close(fd[0]); // 关闭读端

        size_t total = 0;
        char buf[4096]; // 每次写入4KB数据块
        while (1)
        {
            ssize_t n = write(fd[1], buf, sizeof(buf));
            if (n == -1)
            {
                if (errno == EAGAIN)
                { // 管道已满
                    printf("管道缓冲区大小: %zu 字节\n", total);
                    break;
                }
                else
                { // 其他错误
                    perror("写入错误");
                    break;
                }
            }
            else
            {
                total += n; // 累计写入量
            }
        }
        close(fd[1]);
        return 0;
    }
    else
    {                 // 父进程（不操作数据）
        close(fd[1]); // 关闭父进程的写端
        wait(NULL);   // 等待子进程结束
        close(fd[0]);
    }
    return 0;
}